﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ClassForWinForm
{
    public partial class Form16 : Form
    {
        public static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private static byte[] result = new byte[1024];
        private List<Socket> clients = new List<Socket>();
        private List<Socket> closeclients = new List<Socket>();
        public Form16()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void button_Start_Click(object sender, EventArgs e)
        {
            string host = textBox_IP.Text.Trim();//IP地址
            int port = int.Parse(textBox_Port.Text.Trim());//端口
            socket.Bind(new IPEndPoint(IPAddress.Parse(host), port));
            socket.Listen(100);//设定最多100个排队连接请求   
            Thread myThread = new Thread(ListenClientConnect);//通过多线程监听客户端连接  
            myThread.Start();
            textBox_Msg.Text += "服务端已启动\r\n";
        }
        private void ListenClientConnect()
        {
            while (true)
            {
                Socket clientSocket = socket.Accept();
                if (clientSocket != null)
                {
                    clients.Add(clientSocket);
                    label3.Text = clients.Count.ToString();
                }
                Thread receiveThread = new Thread(ReceiveMessage);
                receiveThread.Start(clientSocket);
            }
        }
        private void ReceiveMessage(object clientSocket)
        {
            Socket myClientSocket = (Socket)clientSocket;
            while (true)
            {
                try
                {
                    //判断连接是否断开，  SelectMode.SelectRead读状态模式。
                    //poll已断开返回true
                    if (myClientSocket.Poll(10, SelectMode.SelectRead) == true)
                    {
                        myClientSocket.Close();
                        break;//终止本线程
                    }
                    //通过clientSocket接收数据  
                    int receiveNumber = myClientSocket.Receive(result);
                    if (receiveNumber == 0)
                        return;
                    textBox_Msg.Text += string.Format("接收客户端{0} 的消息：{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.UTF8.GetString(result, 0, receiveNumber)) + "\r\n";
                    //给Client端返回信息
                    //string sendStr = "已成功接到您发送的消息";
                    //byte[] bs = Encoding.UTF8.GetBytes(sendStr);//Encoding.UTF8.GetBytes()不然中文会乱码
                    //myClientSocket.Send(bs, bs.Length, 0);  //返回信息给客户端
                    //myClientSocket.Close(); //发送完数据关闭Socket并释放资源
                    SendAllMessage(myClientSocket.RemoteEndPoint.ToString(), Encoding.UTF8.GetString(result, 0, receiveNumber));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    myClientSocket.Shutdown(SocketShutdown.Both);//禁止发送和上传
                    myClientSocket.Close();//关闭Socket并释放资源
                                           //break;
                }
            }
            
        }
        private void SendAllMessage(string clientname,string message)
        {
            foreach (var client in clients)
            {
                if (client.Connected)
                {
                    string sendStr = string.Format("{0} 的消息：{1}", clientname, message);
                    byte[] data = Encoding.UTF8.GetBytes(sendStr);
                    client.Send(data);
                }
                else
                {
                    closeclients.Add(client);
                }
            }
            foreach (var temp in closeclients)
            {
                clients.Remove(temp);
            }
            label3.Text = clients.Count.ToString();
        }
    }
}
